﻿using LitJson;
using ServerSocket.common;
using ServerSocket.controller;
using ServerSocket.entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace ServerSocket.server
{
    class Server
    {

        private IPAddress ipAddress;
        private int port;
        private Socket serverSocket;
        Message msg = new Message();

        /// <summary>
        /// 控制器管理
        /// </summary>
        private ControllerManager controllerManager;

        /// <summary>
        /// 客户端列表
        /// </summary>
        public List<Client> clientList = new List<Client>();
        public List<Client> ClientList
        {
            get
            {
                return clientList;
            }
            set
            {
                clientList = value;
            }
        }

        /// <summary>
        /// 房间列表
        /// </summary>
        private List<Room> roomList = new List<Room>();
        public List<Room> RoomList
        {
            get
            {
                return roomList;
            }
            set
            {
                roomList = value;
            }
        }

        public Server() { }

        public Server(int port)
        {
            controllerManager = new ControllerManager(this);
            SetIpAndPort(port);
        }

        public Server(string ipStr, int port)
        {
            controllerManager = new ControllerManager(this);
            SetIpAndPort(ipStr, port);
        }

        public Server(IPAddress ipAddress, int port)
        {
            controllerManager = new ControllerManager(this);
            SetIpAndPort(ipAddress, port);
        }

        public void SetIpAndPort(int port)
        {
            this.ipAddress = IPAddress.Any;
            this.port = port;
        }

        public void SetIpAndPort(string ipStr, int port)
        {
            this.ipAddress = IPAddress.Parse(ipStr);
            this.port = port;
        }

        public void SetIpAndPort(IPAddress ipAddress, int port)
        {
            this.ipAddress = ipAddress;
            this.port = port;
        }

        public void Open()
        {
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
            serverSocket.Bind(ipEndPoint);
            serverSocket.Listen(0);
            //接收客户端进来
            serverSocket.BeginAccept(AcceptCallbackAsync, serverSocket);
            Console.WriteLine("服务器已经启动...");
        }

        /// <summary>
        /// 接收客户端回调
        /// </summary>
        /// <param name="ar"></param>
        private void AcceptCallbackAsync(IAsyncResult ar)
        {
            //客户端Socket
            Socket clientSocket = serverSocket.EndAccept(ar);
            Console.WriteLine("已有客户端连接");
            if (clientSocket != null)
            {
                Client client = new Client(clientSocket, this);
                clientList.Add(client);
                //客户端接收数据
                client.Open();
            }
            //继续接收客户端进来
            serverSocket.BeginAccept(AcceptCallbackAsync, serverSocket);
        }

        /// <summary>
        /// 关闭客户端
        /// </summary>
        public void Close()
        {
            if (serverSocket != null)
            {
                Console.WriteLine("关闭服务端连接！！");
                serverSocket.Close();
            }
        }

        /// <summary>
        /// 移除Client
        /// </summary>
        /// <param name="client"></param>
        public void RemoveClient(Client client)
        {
            lock (clientList)
            {
                clientList.Remove(client);
            }
        }

        /// <summary>
        /// 处理客户端请求
        /// </summary>
        public void HandleRequest(string data, Client client)
        {
            controllerManager.HandleRequest(data, client);
        }

        /// <summary>
        /// 给客户端相应
        /// </summary>
        /// <param name="client"></param>
        /// <param name="data"></param>
        public void SendResponse(Client client, string actionCode, string data)
        {
            string res = actionCode + '|' + data;
            client.SendData(res);
        }

        /// <summary>
        /// 给客户端相应（序列化）
        /// </summary>
        /// <param name="client"></param>
        /// <param name="data"></param>
        public void SendResponse<T>(Client client, string actionCode, T data)
        {
            string res = actionCode + '|' + data;
            client.SendData(res);
        }

        /// <summary>
        /// 广播消息给已经连接服务器的客户端
        /// </summary>
        /// <param name="selfClient">发送数据的客户端</param>
        /// <param name="data">数据</param>
        public void BroadcastMessage(Client selfClient, string data)
        {
            foreach (Client client in clientList)
            {
                if (client != selfClient)
                {
                    client.SendData(data);
                }
            }
        }

        /// <summary>
        /// 广播消息给已经连接服务器的客户端（序列化）
        /// </summary>
        /// <param name="selfClient">发送数据的客户端</param>
        /// <param name="data">数据</param>
        public void BroadcastMessage<T>(Client selfClient, T data)
        {
            foreach (Client client in clientList)
            {
                if (client != selfClient)
                {
                    client.SendData(data);
                }
            }
        }

        /// <summary>
        /// 创建房间
        /// </summary>
        /// <param name="client"></param>
        /// <param name="data">用户名</param>
        /// <returns></returns>
        public Room CreateRoom(Client client, string data)
        {
            Room room = JsonMapper.ToObject<Room>(data);
            room.CreateRoom(client, this);
            room.AddClient(client);
            roomList.Add(room);
            client.Room = room;
            return room;
        }

        /// <summary>
        /// 移除房间
        /// </summary>
        /// <returns></returns>
        public void RemoveRoom(Room room) {
            roomList.Remove(room);
        }

        /// <summary>
        /// 根据房间ID找到房间
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Room GetRoomById(string id)
        {
            for (int i = 0; i < roomList.Count; i++)
            {
                if (roomList[i].Id.Equals(id))
                {
                    return roomList[i];
                }
            }
            return null;
        }

        /// <summary>
        /// 搜索正在等待的房间
        /// </summary>
        /// <returns></returns>
        public Room SearchRoom()
        {
            for (int i = 0; i < roomList.Count; i++)
            {
                Room room = roomList[i];
                if (room.Is等待加入)
                {
                    return room;
                }
            }
            return null;
        }

    }
}
